//
//  QRCodeScanVC.swift
//  hkrt
//
//  Created by 文 on 2024/2/5.
//

import Foundation
import AVFoundation
import Photos
import MCToast
import UIKit

class QRCodeScanVC: WHBaseViewVC{
    
    var session: AVCaptureSession!
    var scanLine: UIImageView!
    
    var scanResult = ""
    public var scanResultBlock:((String)->())?

    override func viewDidLoad() {
        super.viewDidLoad()

        buildUI()
    }
    lazy var lightingImgView : UIImageView = {
        let img = UIImageView()
        img.image = UIImage.init(named: "scan_lighting_close_icon")
        img.isUserInteractionEnabled = true
        
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(toggleFlash))
        img.addGestureRecognizer(tap)
        
        return img
    }()
    lazy var tipsLabel : UILabel = {
        let lab = UILabel()
        lab.text = "请将二维码/条形码放入方框中心"
        lab.textColor = .white
        lab.font = .systemFont(ofSize: 15)
        
        return lab
        
    }()
    lazy var photoLibraryBgView : UIView = {
        let vi = UIView()
        vi.backgroundColor = .clear
        vi.layer.borderColor = UIColor.white.cgColor
        vi.layer.borderWidth = kFitWidth(2)
        vi.layer.cornerRadius = kFitWidth(22)
        vi.clipsToBounds = true
        vi.isUserInteractionEnabled = true
        
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(openPhotoLabrary))
        vi.addGestureRecognizer(tap)
        
        return vi
    }()
    lazy var photoImgView : UIImageView = {
        let img = UIImageView()
        img.image = UIImage.init(named: "scan_photo_icon")
        img.isUserInteractionEnabled = true
        
        return img
    }()
    lazy var photoLabel : UILabel = {
        let lab = UILabel()
        lab.text = "去相册选择"
        lab.textColor = .white
        lab.isUserInteractionEnabled = true
        lab.font = .systemFont(ofSize: 16)
        lab.textAlignment = .center
        lab.adjustsFontSizeToFitWidth = true
        
        return lab
    }()
    
    func buildUI() {
        scanQRCode()
        let maskView = SCanMaskView(frame: view.bounds)
        view.addSubview(maskView)
        initNavi(titleStr: "扫码")
//        initUI()
    }
    
    func initUI() {
        initNavi(titleStr: "扫码")
        view.addSubview(lightingImgView)
        view.addSubview(tipsLabel)
        view.addSubview(photoLibraryBgView)
        photoLibraryBgView.addSubview(photoImgView)
        photoLibraryBgView.addSubview(photoLabel)
        
        lightingImgView.snp.makeConstraints { make in
            make.centerX.lessThanOrEqualToSuperview()
            make.top.equalTo(scanQRCodeTop+scanQRCodeWidth+kFitWidth(10))
            make.width.equalTo(kFitWidth(35))
            make.height.equalTo(kFitWidth(37))
        }
        tipsLabel.snp.makeConstraints { make in
            make.centerX.lessThanOrEqualToSuperview()
            make.top.equalTo(lightingImgView.snp.bottom).offset(kFitWidth(20))
        }
        photoLibraryBgView.snp.makeConstraints { make in
            make.centerX.lessThanOrEqualToSuperview()
            make.top.equalTo(tipsLabel.snp.bottom).offset(kFitWidth(30))
            make.width.equalTo(kFitWidth(180))
            make.height.equalTo(kFitWidth(44))
        }
        photoImgView.snp.makeConstraints { make in
            make.centerY.lessThanOrEqualToSuperview()
            make.left.equalTo(kFitWidth(16))
            make.width.equalTo(kFitWidth(25))
            make.height.equalTo(kFitWidth(19))
        }
        photoLabel.snp.makeConstraints { make in
            make.centerY.lessThanOrEqualToSuperview()
            make.left.equalTo(photoImgView.snp.right).offset(kFitWidth(20))
            make.right.equalTo(kFitWidth(-20))
        }
    }
    
    
    func scanQRCode() {
        guard let device = AVCaptureDevice.default(for: .video) else { return }
        do {
            //创建输入流
            let input = try AVCaptureDeviceInput(device: device)
            //创建输出流
            let output = AVCaptureMetadataOutput()
            //设置会话
            session = AVCaptureSession()

            if session.canSetSessionPreset(.high) {
                session.sessionPreset = .high
            }
            if session.canSetSessionPreset(.hd1280x720) {
                session.sessionPreset = .hd1280x720
            }
            if session.canSetSessionPreset(.hd1920x1080) {
                session.sessionPreset = .hd1920x1080
            }
            if session.canSetSessionPreset(.hd4K3840x2160) {
                session.sessionPreset = .hd4K3840x2160
            }
            
            //连接输入输出流
            if session.canAddInput(input) {
                session.addInput(input)
            }
            if session.canAddOutput(output) {
                session.addOutput(output)
            }
            
            //设置扫描码的类型
//            output.metadataObjectTypes = [.qr, .ean13, .ean8, .code128,.aztec,.code39,.code39Mod43,.code93,.dataMatrix,.interleaved2of5,.itf14,.upce]
//            output.metadataObjectTypes = [.ean13, .ean8, .code128,.qr]
//            output.metadataObjectTypes = [.qr]
            output.metadataObjectTypes = output.availableMetadataObjectTypes
            output.setMetadataObjectsDelegate(self, queue: .main)
            //设置扫描区域
            output.rectOfInterest = CGRect(x: scanQRCodeTop / screenHeight, y: (( screenWidth - scanQRCodeWidth ) / 2 ) / screenWidth, width: scanQRCodeWidth / screenHeight, height: scanQRCodeWidth / screenWidth)
            //捕捉图层
            let previewLayer = AVCaptureVideoPreviewLayer(session: session)
            previewLayer.videoGravity = .resizeAspectFill
            previewLayer.frame = view.layer.bounds
//            view.layer.addSublayer(previewLayer)
            view.layer.insertSublayer(previewLayer, at: 0)
            session.startRunning()
        }catch {
            
        }
    }
}

extension QRCodeScanVC: AVCaptureMetadataOutputObjectsDelegate {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        
        guard let readableObject = metadataObjects.first as? AVMetadataMachineReadableCodeObject else {
            return
        }
        
        DLLog(message: "\(readableObject)")
        
        if let str = readableObject.stringValue {
            self.scanResult = str
            print(str)
            if self.scanResultBlock != nil{
                self.scanResultBlock!(str)
            }
            session.stopRunning()
            self.backTapAction()
        }
    }
}

extension QRCodeScanVC:UIImagePickerControllerDelegate & UINavigationControllerDelegate{
    @objc private func openPhotoLabrary() {
        let picker = UIImagePickerController()
        picker.title = "Photos"
        picker.delegate = self
        picker.allowsEditing = true
        picker.sourceType = .photoLibrary
        picker.navigationBar.barStyle = .default
        self.present(picker, animated: true, completion: nil)
    }
    func imagePickerController(_ picker: UIImagePickerController,
                               didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        dismiss(animated: true)
        
        guard let image = info[.originalImage] as? UIImage else {
            print("choose not image")
            return
        }
        guard let ciImage = CIImage(image: image) else
        {
            return
        }
        let detector = CIDetector(ofType: CIDetectorTypeQRCode, context: nil, options: [CIDetectorAccuracy: CIDetectorAccuracyLow])
            // 2.2利用探测器探测数据
            let results = detector!.features(in: ciImage)
            // 2.3取出探测到的数据
            for result in results
            {
                self.scanResult = "\((result as! CIQRCodeFeature).messageString ?? "")"
                DLLog(message: "\(self.scanResult)")
            }
        }
}


extension QRCodeScanVC{
    @objc func toggleFlash() {
        let device = AVCaptureDevice.default(for: AVMediaType.video)
        if (device?.hasTorch == true) {
            do {
                try device?.lockForConfiguration()
                if (device?.torchMode == AVCaptureDevice.TorchMode.on) {
                    device?.torchMode = AVCaptureDevice.TorchMode.off
                    self.lightingImgView.image = UIImage.init(named: "scan_lighting_close_icon")
                } else {
                    do {
                        try device?.setTorchModeOn(level: 1.0)
                        self.lightingImgView.image = UIImage.init(named: "scan_lighting_open_icon")
                    } catch {
                        print(error)
                    }
                }
                device?.unlockForConfiguration()
            } catch {
                print(error)
            }
        }
    }
}
